package club.cearnach.api.listener;

import club.cearnach.entity.Visitor;
import club.cearnach.api.service.IVisitorService;
import club.cearnach.core.util.UserAgentUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;

/**
 * Session监听器,用于统计在线人数和访问总人数
 *
 * @author 阮胜
 * @date 2018/5/16 14:57
 */
@WebListener
@Slf4j
public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {
    private static final String TOTAL_VISITORS = "totalVisitors";
    private static final String ONLINE_VISITORS = "onlineVisitors";
    private final IVisitorService visitorService;
    private final StringRedisTemplate stringRedisTemplate;

    public SessionListener(IVisitorService visitorService, StringRedisTemplate stringRedisTemplate) {
        this.visitorService = visitorService;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        ops.increment(TOTAL_VISITORS, 1);
        ops.increment(ONLINE_VISITORS, 1);
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = req.getRemoteAddr();
        String terminal = UserAgentUtil.getUserAgent(req);
        Visitor visitor = new Visitor(ip, terminal);
        visitorService.save(visitor);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        stringRedisTemplate.opsForValue().increment(ONLINE_VISITORS, -1);
    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
    }
}